//
// (c) 2000 Sun Microsystems, Inc.
// ALL RIGHTS RESERVED
// 
// License Grant-
// 
// 
// Permission to use, copy, modify, and distribute this Software and its 
// documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is 
// hereby granted.  
// 
// This Software is provided "AS IS".  All express warranties, including any 
// implied warranty of merchantability, satisfactory quality, fitness for a 
// particular purpose, or non-infringement, are disclaimed, except to the extent 
// that such disclaimers are held to be legally invalid.
// 
// You acknowledge that Software is not designed, licensed or intended for use in 
// the design, construction, operation or maintenance of any nuclear facility 
// ("High Risk Activities").  Sun disclaims any express or implied warranty of 
// fitness for such uses.  
//
// Please refer to the file http://www.sun.com/policies/trademarks/ for further 
// important trademark information and to 
// http://java.sun.com/nav/business/index.html for further important licensing 
// information for the Java Technology.
//
using System;
namespace Suake2.UI.util
{
	
	/// <summary> PrintfFormat allows the formatting of an array of
	/// objects embedded within a string.  Primitive types
	/// must be passed using wrapper types.  The formatting
	/// is controlled by a control string.
	/// <p>
	/// A control string is a Java string that contains a
	/// control specification.  The control specification
	/// starts at the first percent sign (%) in the string,
	/// provided that this percent sign
	/// <ol>
	/// <li>is not escaped protected by a matching % or is
	/// not an escape % character,
	/// <li>is not at the end of the format string, and
	/// <li>precedes a sequence of characters that parses as
	/// a valid control specification.
	/// </ol>
	/// </p><p>
	/// A control specification usually takes the form:
	/// <pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
	/// { [hlL] }+ [idfgGoxXeEcs]
	/// </pre>
	/// There are variants of this basic form that are
	/// discussed below.</p>
	/// <p>
	/// The format is composed of zero or more directives
	/// defined as follows:
	/// <ul>
	/// <li>ordinary characters, which are simply copied to
	/// the output stream;
	/// <li>escape sequences, which represent non-graphic
	/// characters; and
	/// <li>conversion specifications,  each of which
	/// results in the fetching of zero or more arguments.
	/// </ul></p>
	/// <p>
	/// The results are undefined if there are insufficient
	/// arguments for the format.  Usually an unchecked
	/// exception will be thrown.  If the format is
	/// exhausted while arguments remain, the excess
	/// arguments are evaluated but are otherwise ignored.
	/// In format strings containing the % form of
	/// conversion specifications, each argument in the
	/// argument list is used exactly once.</p>
	/// <p>
	/// Conversions can be applied to the <code>n</code>th
	/// argument after the format in the argument list,
	/// rather than to the next unused argument.  In this
	/// case, the conversion characer % is replaced by the
	/// sequence %<code>n</code>$, where <code>n</code> is
	/// a decimal integer giving the position of the
	/// argument in the argument list.</p>
	/// <p>
	/// In format strings containing the %<code>n</code>$
	/// form of conversion specifications, each argument
	/// in the argument list is used exactly once.</p>
	/// 
	/// <h4>Escape Sequences</h4>
	/// <p>
	/// The following table lists escape sequences and
	/// associated actions on display devices capable of
	/// the action.
	/// <table>
	/// <tr><th align=left>Sequence</th>
	/// <th align=left>Name</th>
	/// <th align=left>Description</th></tr>
	/// <tr><td>\\</td><td>backlash</td><td>None.
	/// </td></tr>
	/// <tr><td>\a</td><td>alert</td><td>Attempts to alert
	/// the user through audible or visible
	/// notification.
	/// </td></tr>
	/// <tr><td>\b</td><td>backspace</td><td>Moves the
	/// printing position to one column before
	/// the current position, unless the
	/// current position is the start of a line.
	/// </td></tr>
	/// <tr><td>\f</td><td>form-feed</td><td>Moves the
	/// printing position to the initial 
	/// printing position of the next logical
	/// page.
	/// </td></tr>
	/// <tr><td>\n</td><td>newline</td><td>Moves the
	/// printing position to the start of the
	/// next line.
	/// </td></tr>
	/// <tr><td>\r</td><td>carriage-return</td><td>Moves
	/// the printing position to the start of
	/// the current line.
	/// </td></tr>
	/// <tr><td>\t</td><td>tab</td><td>Moves the printing
	/// position to the next implementation-
	/// defined horizontal tab position.
	/// </td></tr>
	/// <tr><td>\v</td><td>vertical-tab</td><td>Moves the
	/// printing position to the start of the
	/// next implementation-defined vertical
	/// tab position.
	/// </td></tr>
	/// </table></p>
	/// <h4>Conversion Specifications</h4>
	/// <p>
	/// Each conversion specification is introduced by
	/// the percent sign character (%).  After the character
	/// %, the following appear in sequence:</p>
	/// <p>
	/// Zero or more flags (in any order), which modify the
	/// meaning of the conversion specification.</p>
	/// <p>
	/// An optional minimum field width.  If the converted
	/// value has fewer characters than the field width, it
	/// will be padded with spaces by default on the left;
	/// t will be padded on the right, if the left-
	/// adjustment flag (-), described below, is given to
	/// the field width.  The field width takes the form
	/// of a decimal integer.  If the conversion character
	/// is s, the field width is the the minimum number of
	/// characters to be printed.</p>
	/// <p>
	/// An optional precision that gives the minumum number
	/// of digits to appear for the d, i, o, x or X
	/// conversions (the field is padded with leading
	/// zeros); the number of digits to appear after the
	/// radix character for the e, E, and f conversions,
	/// the maximum number of significant digits for the g
	/// and G conversions; or the maximum number of
	/// characters to be written from a string is s and S
	/// conversions.  The precision takes the form of an
	/// optional decimal digit string, where a null digit
	/// string is treated as 0.  If a precision appears
	/// with a c conversion character the precision is
	/// ignored.
	/// </p>
	/// <p>
	/// An optional h specifies that a following d, i, o,
	/// x, or X conversion character applies to a type 
	/// short argument (the argument will be promoted
	/// according to the integral promotions and its value
	/// converted to type short before printing).</p>
	/// <p>
	/// An optional l (ell) specifies that a following
	/// d, i, o, x, or X conversion character applies to a
	/// type long argument.</p>
	/// <p>
	/// A field width or precision may be indicated by an
	/// asterisk (*) instead of a digit string.  In this
	/// case, an integer argument supplised the field width
	/// precision.  The argument that is actually converted
	/// is not fetched until the conversion letter is seen,
	/// so the the arguments specifying field width or
	/// precision must appear before the argument (if any)
	/// to be converted.  If the precision argument is
	/// negative, it will be changed to zero.  A negative
	/// field width argument is taken as a - flag, followed
	/// by a positive field width.</p>
	/// <p>
	/// In format strings containing the %<code>n</code>$
	/// form of a conversion specification, a field width
	/// or precision may be indicated by the sequence
	/// *<code>m</code>$, where m is a decimal integer
	/// giving the position in the argument list (after the
	/// format argument) of an integer argument containing
	/// the field width or precision.</p>
	/// <p>
	/// The format can contain either numbered argument
	/// specifications (that is, %<code>n</code>$ and
	/// *<code>m</code>$), or unnumbered argument
	/// specifications (that is % and *), but normally not
	/// both.  The only exception to this is that %% can
	/// be mixed with the %<code>n</code>$ form.  The
	/// results of mixing numbered and unnumbered argument
	/// specifications in a format string are undefined.</p>
	/// 
	/// <h4>Flag Characters</h4>
	/// <p>
	/// The flags and their meanings are:</p>
	/// <dl>
	/// <dt>'<dd> integer portion of the result of a
	/// decimal conversion (%i, %d, %f, %g, or %G) will
	/// be formatted with thousands' grouping
	/// characters.  For other conversions the flag
	/// is ignored.  The non-monetary grouping
	/// character is used.
	/// <dt>-<dd> result of the conversion is left-justified
	/// within the field.  (It will be right-justified
	/// if this flag is not specified).</td></tr>
	/// <dt>+<dd> result of a signed conversion always
	/// begins with a sign (+ or -).  (It will begin
	/// with a sign only when a negative value is
	/// converted if this flag is not specified.)
	/// <dt>&lt;space&gt;<dd> If the first character of a
	/// signed conversion is not a sign, a space
	/// character will be placed before the result.
	/// This means that if the space character and +
	/// flags both appear, the space flag will be
	/// ignored.
	/// <dt>#<dd> value is to be converted to an alternative
	/// form.  For c, d, i, and s conversions, the flag
	/// has no effect.  For o conversion, it increases
	/// the precision to force the first digit of the
	/// result to be a zero.  For x or X conversion, a
	/// non-zero result has 0x or 0X prefixed to it,
	/// respectively.  For e, E, f, g, and G
	/// conversions, the result always contains a radix
	/// character, even if no digits follow the radix
	/// character (normally, a decimal point appears in
	/// the result of these conversions only if a digit
	/// follows it).  For g and G conversions, trailing
	/// zeros will not be removed from the result as
	/// they normally are.
	/// <dt>0<dd> d, i, o, x, X, e, E, f, g, and G
	/// conversions, leading zeros (following any
	/// indication of sign or base) are used to pad to
	/// the field width;  no space padding is
	/// performed.  If the 0 and - flags both appear,
	/// the 0 flag is ignored.  For d, i, o, x, and X
	/// conversions, if a precision is specified, the
	/// 0 flag will be ignored. For c conversions,
	/// the flag is ignored.
	/// </dl>
	/// 
	/// <h4>Conversion Characters</h4>
	/// <p>
	/// Each conversion character results in fetching zero
	/// or more arguments.  The results are undefined if
	/// there are insufficient arguments for the format.
	/// Usually, an unchecked exception will be thrown.
	/// If the format is exhausted while arguments remain,
	/// the excess arguments are ignored.</p>
	/// 
	/// <p>
	/// The conversion characters and their meanings are:
	/// </p>
	/// <dl>
	/// <dt>d,i<dd>The int argument is converted to a
	/// signed decimal in the style [-]dddd.  The
	/// precision specifies the minimum number of
	/// digits to appear;  if the value being
	/// converted can be represented in fewer
	/// digits, it will be expanded with leading
	/// zeros.  The default precision is 1.  The
	/// result of converting 0 with an explicit
	/// precision of 0 is no characters.
	/// <dt>o<dd> The int argument is converted to unsigned
	/// octal format in the style ddddd.  The
	/// precision specifies the minimum number of
	/// digits to appear;  if the value being
	/// converted can be represented in fewer
	/// digits, it will be expanded with leading
	/// zeros.  The default precision is 1.  The
	/// result of converting 0 with an explicit
	/// precision of 0 is no characters.
	/// <dt>x<dd> The int argument is converted to unsigned
	/// hexadecimal format in the style dddd;  the
	/// letters abcdef are used.  The precision
	/// specifies the minimum numberof digits to
	/// appear; if the value being converted can be
	/// represented in fewer digits, it will be
	/// expanded with leading zeros.  The default
	/// precision is 1.  The result of converting 0
	/// with an explicit precision of 0 is no
	/// characters.
	/// <dt>X<dd> Behaves the same as the x conversion
	/// character except that letters ABCDEF are
	/// used instead of abcdef.
	/// <dt>f<dd> The floating point number argument is
	/// written in decimal notation in the style
	/// [-]ddd.ddd, where the number of digits after
	/// the radix character (shown here as a decimal
	/// point) is equal to the precision
	/// specification.  A Locale is used to determine
	/// the radix character to use in this format.
	/// If the precision is omitted from the
	/// argument, six digits are written after the
	/// radix character;  if the precision is
	/// explicitly 0 and the # flag is not specified,
	/// no radix character appears.  If a radix
	/// character appears, at least 1 digit appears
	/// before it.  The value is rounded to the
	/// appropriate number of digits.
	/// <dt>e,E<dd>The floating point number argument is
	/// written in the style [-]d.ddde{+-}dd
	/// (the symbols {+-} indicate either a plus or
	/// minus sign), where there is one digit before
	/// the radix character (shown here as a decimal
	/// point) and the number of digits after it is
	/// equal to the precision.  A Locale is used to
	/// determine the radix character to use in this
	/// format.  When the precision is missing, six
	/// digits are written after the radix character;
	/// if the precision is 0 and the # flag is not
	/// specified, no radix character appears.  The
	/// E conversion will produce a number with E
	/// instead of e introducing the exponent.  The
	/// exponent always contains at least two digits.
	/// However, if the value to be written requires
	/// an exponent greater than two digits,
	/// additional exponent digits are written as
	/// necessary.  The value is rounded to the
	/// appropriate number of digits.
	/// <dt>g,G<dd>The floating point number argument is
	/// written in style f or e (or in sytle E in the
	/// case of a G conversion character), with the
	/// precision specifying the number of
	/// significant digits.  If the precision is
	/// zero, it is taken as one.  The style used
	/// depends on the value converted:  style e
	/// (or E) will be used only if the exponent
	/// resulting from the conversion is less than
	/// -4 or greater than or equal to the precision.
	/// Trailing zeros are removed from the result.
	/// A radix character appears only if it is
	/// followed by a digit.
	/// <dt>c,C<dd>The integer argument is converted to a
	/// char and the result is written.
	/// 
	/// <dt>s,S<dd>The argument is taken to be a string and
	/// bytes from the string are written until the
	/// end of the string or the number of bytes 
	/// indicated by the precision specification of
	/// the argument is reached.  If the precision
	/// is omitted from the argument, it is taken to
	/// be infinite, so all characters up to the end
	/// of the string are written.
	/// <dt>%<dd>Write a % character;  no argument is
	/// converted.
	/// </dl>
	/// <p>
	/// If a conversion specification does not match one of
	/// the above forms, an IllegalArgumentException is
	/// thrown and the instance of PrintfFormat is not
	/// created.</p>
	/// <p>
	/// If a floating point value is the internal
	/// representation for infinity, the output is
	/// [+]Infinity, where Infinity is either Infinity or
	/// Inf, depending on the desired output string length.
	/// Printing of the sign follows the rules described
	/// above.</p>
	/// <p>
	/// If a floating point value is the internal
	/// representation for "not-a-number," the output is
	/// [+]NaN.  Printing of the sign follows the rules
	/// described above.</p>
	/// <p>
	/// In no case does a non-existent or small field width
	/// cause truncation of a field;  if the result of a
	/// conversion is wider than the field width, the field
	/// is simply expanded to contain the conversion result.
	/// </p>
	/// <p>
	/// The behavior is like printf.  One exception is that
	/// the minimum number of exponent digits is 3 instead
	/// of 2 for e and E formats when the optional L is used
	/// before the e, E, g, or G conversion character.  The
	/// optional L does not imply conversion to a long long
	/// double. </p>
	/// <p>
	/// The biggest divergence from the C printf
	/// specification is in the use of 16 bit characters.
	/// This allows the handling of characters beyond the
	/// small ASCII character set and allows the utility to
	/// interoperate correctly with the rest of the Java
	/// runtime environment.</p>
	/// <p>
	/// Omissions from the C printf specification are
	/// numerous.  All the known omissions are present
	/// because Java never uses bytes to represent
	/// characters and does not have pointers:</p>
	/// <ul>
	/// <li>%c is the same as %C.
	/// <li>%s is the same as %S.
	/// <li>u, p, and n conversion characters. 
	/// <li>%ws format.
	/// <li>h modifier applied to an n conversion character.
	/// <li>l (ell) modifier applied to the c, n, or s
	/// conversion characters.
	/// <li>ll (ell ell) modifier to d, i, o, u, x, or X
	/// conversion characters.
	/// <li>ll (ell ell) modifier to an n conversion
	/// character.
	/// <li>c, C, d,i,o,u,x, and X conversion characters
	/// apply to Byte, Character, Short, Integer, Long
	/// types.
	/// <li>f, e, E, g, and G conversion characters apply
	/// to Float and Double types.
	/// <li>s and S conversion characters apply to String
	/// types.
	/// <li>All other reference types can be formatted
	/// using the s or S conversion characters only.
	/// </ul>
	/// <p>
	/// Most of this specification is quoted from the Unix
	/// man page for the sprintf utility.</p>
	/// 
	/// </summary>
	/// <author>  Allan Jacobs
	/// </author>
	/// <version>  1
	/// Release 1: Initial release.
	/// Release 2: Asterisk field widths and precisions    
	/// %n$ and *m$
	/// Bug fixes
	/// g format fix (2 digits in e form corrupt)
	/// rounding in f format implemented
	/// round up when digit not printed is 5
	/// formatting of -0.0f
	/// round up/down when last digits are 50000...
	/// </version>
	public class PrintfFormat
	{
		/// <summary> Constructs an array of control specifications
		/// possibly preceded, separated, or followed by
		/// ordinary strings.  Control strings begin with
		/// unpaired percent signs.  A pair of successive
		/// percent signs designates a single percent sign in
		/// the format.
		/// </summary>
		/// <param name="fmtArg"> Control string.
		/// </param>
		/// <exception cref="IllegalArgumentException">if the control
		/// string is null, zero length, or otherwise
		/// malformed.
		/// </exception>
		//UPGRADE_TODO: Method 'java.util.Locale.getDefault' was converted to 'System.Threading.Thread.CurrentThread.CurrentCulture' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073'"
		public PrintfFormat(System.String fmtArg):this(System.Threading.Thread.CurrentThread.CurrentCulture, fmtArg)
		{
		}
		/// <summary> Constructs an array of control specifications
		/// possibly preceded, separated, or followed by
		/// ordinary strings.  Control strings begin with
		/// unpaired percent signs.  A pair of successive
		/// percent signs designates a single percent sign in
		/// the format.
		/// </summary>
		/// <param name="fmtArg"> Control string.
		/// </param>
		/// <exception cref="IllegalArgumentException">if the control
		/// string is null, zero length, or otherwise
		/// malformed.
		/// </exception>
		public PrintfFormat(System.Globalization.CultureInfo locale, System.String fmtArg)
		{
			dfs = locale.NumberFormat;
			int ePos = 0;
			ConversionSpecification sFmt = null;
			System.String unCS = this.nonControl(fmtArg, 0);
			if (unCS != null)
			{
				sFmt = new ConversionSpecification(this);
				sFmt.Literal = unCS;
				vFmt.Add(sFmt);
			}
			while (cPos != - 1 && cPos < fmtArg.Length)
			{
				for (ePos = cPos + 1; ePos < fmtArg.Length; ePos++)
				{
					char c = (char) (0);
					c = fmtArg[ePos];
					if (c == 'i')
						break;
					if (c == 'd')
						break;
					if (c == 'f')
						break;
					if (c == 'g')
						break;
					if (c == 'G')
						break;
					if (c == 'o')
						break;
					if (c == 'x')
						break;
					if (c == 'X')
						break;
					if (c == 'e')
						break;
					if (c == 'E')
						break;
					if (c == 'c')
						break;
					if (c == 's')
						break;
					if (c == '%')
						break;
				}
				ePos = System.Math.Min(ePos + 1, fmtArg.Length);
				sFmt = new ConversionSpecification(this, fmtArg.Substring(cPos, (ePos) - (cPos)));
				vFmt.Add(sFmt);
				unCS = this.nonControl(fmtArg, ePos);
				if (unCS != null)
				{
					sFmt = new ConversionSpecification(this);
					sFmt.Literal = unCS;
					vFmt.Add(sFmt);
				}
			}
		}
		/// <summary> Return a substring starting at
		/// <code>start</code> and ending at either the end
		/// of the String <code>s</code>, the next unpaired
		/// percent sign, or at the end of the String if the
		/// last character is a percent sign.
		/// </summary>
		/// <param name="s"> Control string.
		/// </param>
		/// <param name="start">Position in the string
		/// <code>s</code> to begin looking for the start
		/// of a control string.
		/// </param>
		/// <returns> the substring from the start position
		/// to the beginning of the control string.
		/// </returns>
		private System.String nonControl(System.String s, int start)
		{
			System.String ret = "";
			//UPGRADE_WARNING: Method 'java.lang.String.indexOf' was converted to 'System.String.IndexOf' which may throw an exception. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1101'"
			cPos = s.IndexOf("%", start);
			if (cPos == - 1)
				cPos = s.Length;
			return s.Substring(start, (cPos) - (start));
		}
		/// <summary> Format an array of objects.  Byte, Short,
		/// Integer, Long, Float, Double, and Character
		/// arguments are treated as wrappers for primitive
		/// types.
		/// </summary>
		/// <param name="o">The array of objects to format.
		/// </param>
		/// <returns>  The formatted String.
		/// </returns>
		public virtual System.String sprintf(System.Object[] o)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			int i = 0;
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
				{
					if (cs.PositionalSpecification)
					{
						i = cs.ArgumentPosition - 1;
						if (cs.PositionalFieldWidth)
						{
							int ifw = cs.ArgumentPositionForFieldWidth - 1;
							cs.FieldWidthWithArg = ((System.Int32) o[ifw]);
						}
						if (cs.PositionalPrecision)
						{
							int ipr = cs.ArgumentPositionForPrecision - 1;
							cs.PrecisionWithArg = ((System.Int32) o[ipr]);
						}
					}
					else
					{
						if (cs.VariableFieldWidth)
						{
							cs.FieldWidthWithArg = ((System.Int32) o[i]);
							i++;
						}
						if (cs.VariablePrecision)
						{
							cs.PrecisionWithArg = ((System.Int32) o[i]);
							i++;
						}
					}
					if (o[i] is System.SByte)
						sb.Append(cs.internalsprintf((sbyte) ((System.SByte) o[i])));
					else if (o[i] is System.Int16)
						sb.Append(cs.internalsprintf((short) ((System.Int16) o[i])));
					else if (o[i] is System.Int32)
						sb.Append(cs.internalsprintf(((System.Int32) o[i])));
					else if (o[i] is System.Int64)
						sb.Append(cs.internalsprintf((long) ((System.Int64) o[i])));
					else if (o[i] is System.Single)
					{
						//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
						sb.Append(cs.internalsprintf((float) ((System.Single) o[i])));
					}
					else if (o[i] is System.Double)
						sb.Append(cs.internalsprintf(((System.Double) o[i])));
					else if (o[i] is System.Char)
						sb.Append(cs.internalsprintf(((System.Char) o[i])));
					else if (o[i] is System.String)
						sb.Append(cs.internalsprintf((System.String) o[i]));
					else
						sb.Append(cs.internalsprintf(o[i]));
					if (!cs.PositionalSpecification)
						i++;
				}
			}
			return sb.ToString();
		}
		/// <summary> Format nothing.  Just use the control string.</summary>
		/// <returns>  the formatted String.
		/// </returns>
		public virtual System.String sprintf()
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
			}
			return sb.ToString();
		}
		/// <summary> Format an int.</summary>
		/// <param name="x">The int to format.
		/// </param>
		/// <returns>  The formatted String.
		/// </returns>
		/// <exception cref="IllegalArgumentException">if the
		/// conversion character is f, e, E, g, G, s,
		/// or S.
		/// </exception>
		public virtual System.String sprintf(int x)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
					sb.Append(cs.internalsprintf(x));
			}
			return sb.ToString();
		}
		/// <summary> Format an long.</summary>
		/// <param name="x">The long to format.
		/// </param>
		/// <returns>  The formatted String.
		/// </returns>
		/// <exception cref="IllegalArgumentException">if the
		/// conversion character is f, e, E, g, G, s,
		/// or S.
		/// </exception>
		public virtual System.String sprintf(long x)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
					sb.Append(cs.internalsprintf(x));
			}
			return sb.ToString();
		}
		/// <summary> Format a double.</summary>
		/// <param name="x">The double to format.
		/// </param>
		/// <returns>  The formatted String.
		/// </returns>
		/// <exception cref="IllegalArgumentException">if the
		/// conversion character is c, C, s, S,
		/// d, d, x, X, or o.
		/// </exception>
		public virtual System.String sprintf(double x)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
					sb.Append(cs.internalsprintf(x));
			}
			return sb.ToString();
		}
		/// <summary> Format a String.</summary>
		/// <param name="x">The String to format.
		/// </param>
		/// <returns>  The formatted String.
		/// </returns>
		/// <exception cref="IllegalArgumentException">if the
		/// conversion character is neither s nor S.
		/// </exception>
		public virtual System.String sprintf(System.String x)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
					sb.Append(cs.internalsprintf(x));
			}
			return sb.ToString();
		}
		/// <summary> Format an Object.  Convert wrapper types to
		/// their primitive equivalents and call the
		/// appropriate internal formatting method. Convert
		/// Strings using an internal formatting method for
		/// Strings. Otherwise use the default formatter
		/// (use toString).
		/// </summary>
		/// <param name="x">the Object to format.
		/// </param>
		/// <returns>  the formatted String.
		/// </returns>
		/// <exception cref="IllegalArgumentException">if the
		/// conversion character is inappropriate for
		/// formatting an unwrapped value.
		/// </exception>
		public virtual System.String sprintf(System.Object x)
		{
			System.Collections.IEnumerator e = vFmt.GetEnumerator();
			ConversionSpecification cs = null;
			char c = (char) (0);
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (e.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				cs = (ConversionSpecification) e.Current;
				c = cs.getConversionCharacter();
				if (c == '\x0000')
					sb.Append(cs.Literal);
				else if (c == '%')
					sb.Append("%");
				else
				{
					if (x is System.SByte)
						sb.Append(cs.internalsprintf((sbyte) ((System.SByte) x)));
					else if (x is System.Int16)
						sb.Append(cs.internalsprintf((short) ((System.Int16) x)));
					else if (x is System.Int32)
						sb.Append(cs.internalsprintf(((System.Int32) x)));
					else if (x is System.Int64)
						sb.Append(cs.internalsprintf((long) ((System.Int64) x)));
					else if (x is System.Single)
					{
						//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
						sb.Append(cs.internalsprintf((float) ((System.Single) x)));
					}
					else if (x is System.Double)
						sb.Append(cs.internalsprintf(((System.Double) x)));
					else if (x is System.Char)
						sb.Append(cs.internalsprintf(((System.Char) x)));
					else if (x is System.String)
						sb.Append(cs.internalsprintf((System.String) x));
					else
						sb.Append(cs.internalsprintf(x));
				}
			}
			return sb.ToString();
		}
		//UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'ConversionSpecification' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
		/// <summary><p>
		/// ConversionSpecification allows the formatting of
		/// a single primitive or object embedded within a
		/// string.  The formatting is controlled by a
		/// format string.  Only one Java primitive or
		/// object can be formatted at a time.
		/// <p>
		/// A format string is a Java string that contains
		/// a control string.  The control string starts at
		/// the first percent sign (%) in the string,
		/// provided that this percent sign
		/// <ol>
		/// <li>is not escaped protected by a matching % or
		/// is not an escape % character,
		/// <li>is not at the end of the format string, and
		/// <li>precedes a sequence of characters that parses
		/// as a valid control string.
		/// </ol>
		/// <p>
		/// A control string takes the form:
		/// <pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
		/// { [hlL] }+ [idfgGoxXeEcs]
		/// </pre>
		/// <p>
		/// The behavior is like printf.  One (hopefully the
		/// only) exception is that the minimum number of
		/// exponent digits is 3 instead of 2 for e and E
		/// formats when the optional L is used before the
		/// e, E, g, or G conversion character.  The 
		/// optional L does not imply conversion to a long
		/// long double.
		/// </summary>
		private class ConversionSpecification
		{
			private void  InitBlock(PrintfFormat enclosingInstance)
			{
				this.enclosingInstance = enclosingInstance;
			}
			private PrintfFormat enclosingInstance;
			//UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
			/// <summary> Get the String for this instance.  Translate
			/// any escape sequences.
			/// 
			/// </summary>
			/// <returns> s the stored String.
			/// </returns>
			/// <summary> Set the String for this instance.</summary>
			/// <param name="s">the String to store.
			/// </param>
			virtual internal System.String Literal
			{
				get
				{
					System.Text.StringBuilder sb = new System.Text.StringBuilder();
					int i = 0;
					while (i < fmt.Length)
					{
						if (fmt[i] == '\\')
						{
							i++;
							if (i < fmt.Length)
							{
								char c = fmt[i];
								switch (c)
								{
									
									case 'a': 
										sb.Append((char) 0x07);
										break;
									
									case 'b': 
										sb.Append('\b');
										break;
									
									case 'f': 
										sb.Append('\f');
										break;
									
									case 'n': 
										sb.Append(System.Environment.NewLine);
										break;
									
									case 'r': 
										sb.Append('\r');
										break;
									
									case 't': 
										sb.Append('\t');
										break;
									
									case 'v': 
										sb.Append((char) 0x0b);
										break;
									
									case '\\': 
										sb.Append('\\');
										break;
									}
								i++;
							}
							else
								sb.Append('\\');
						}
						else
							i++;
					}
					return fmt;
				}
				
				set
				{
					fmt = value;
				}
				
			}
			/// <summary> Check whether the specifier has a variable
			/// field width that is going to be set by an
			/// argument.
			/// </summary>
			/// <returns> <code>true</code> if the conversion
			/// uses an * field width; otherwise
			/// <code>false</code>.
			/// </returns>
			virtual internal bool VariableFieldWidth
			{
				get
				{
					return variableFieldWidth;
				}
				
			}
			/// <summary> Set the field width with an argument.  A
			/// negative field width is taken as a - flag
			/// followed by a positive field width.
			/// </summary>
			/// <param name="fw">the field width.
			/// </param>
			virtual internal int FieldWidthWithArg
			{
				set
				{
					if (value < 0)
						leftJustify = true;
					fieldWidthSet = true;
					fieldWidth = System.Math.Abs(value);
				}
				
			}
			/// <summary> Check whether the specifier has a variable
			/// precision that is going to be set by an
			/// argument.
			/// </summary>
			/// <returns> <code>true</code> if the conversion
			/// uses an * precision; otherwise
			/// <code>false</code>.
			/// </returns>
			virtual internal bool VariablePrecision
			{
				get
				{
					return variablePrecision;
				}
				
			}
			/// <summary> Set the precision with an argument.  A
			/// negative precision will be changed to zero.
			/// </summary>
			/// <param name="pr">the precision.
			/// </param>
			virtual internal int PrecisionWithArg
			{
				set
				{
					precisionSet = true;
					precision = System.Math.Max(value, 0);
				}
				
			}
			virtual internal bool PositionalSpecification
			{
				get
				{
					return positionalSpecification;
				}
				
			}
			virtual internal int ArgumentPosition
			{
				get
				{
					return argumentPosition;
				}
				
			}
			virtual internal bool PositionalFieldWidth
			{
				get
				{
					return positionalFieldWidth;
				}
				
			}
			virtual internal int ArgumentPositionForFieldWidth
			{
				get
				{
					return argumentPositionForFieldWidth;
				}
				
			}
			virtual internal bool PositionalPrecision
			{
				get
				{
					return positionalPrecision;
				}
				
			}
			virtual internal int ArgumentPositionForPrecision
			{
				get
				{
					return argumentPositionForPrecision;
				}
				
			}
			public PrintfFormat Enclosing_Instance
			{
				get
				{
					return enclosingInstance;
				}
				
			}
			/// <summary> Constructor.  Used to prepare an instance
			/// to hold a literal, not a control string.
			/// </summary>
			internal ConversionSpecification(PrintfFormat enclosingInstance)
			{
				InitBlock(enclosingInstance);
			}
			/// <summary> Constructor for a conversion specification.
			/// The argument must begin with a % and end
			/// with the conversion character for the
			/// conversion specification.
			/// </summary>
			/// <param name="fmtArg"> String specifying the
			/// conversion specification.
			/// </param>
			/// <exception cref="IllegalArgumentException">if the
			/// input string is null, zero length, or
			/// otherwise malformed.
			/// </exception>
			internal ConversionSpecification(PrintfFormat enclosingInstance, System.String fmtArg)
			{
				InitBlock(enclosingInstance);
				if (fmtArg == null)
					throw new System.NullReferenceException();
				if (fmtArg.Length == 0)
					throw new System.ArgumentException("Control strings must have positive" + " lengths.");
				if (fmtArg[0] == '%')
				{
					fmt = fmtArg;
					pos = 1;
					setArgPosition();
					setFlagCharacters();
					setFieldWidth();
					setPrecision();
					setOptionalHL();
					if (setConversionCharacter())
					{
						if (pos == fmtArg.Length)
						{
							if (leadingZeros && leftJustify)
								leadingZeros = false;
							if (precisionSet && leadingZeros)
							{
								if (conversionCharacter == 'd' || conversionCharacter == 'i' || conversionCharacter == 'o' || conversionCharacter == 'x')
								{
									leadingZeros = false;
								}
							}
						}
						else
							throw new System.ArgumentException("Malformed conversion specification=" + fmtArg);
					}
					else
						throw new System.ArgumentException("Malformed conversion specification=" + fmtArg);
				}
				else
					throw new System.ArgumentException("Control strings must begin with %.");
			}
			/// <summary> Get the conversion character that tells what
			/// type of control character this instance has.
			/// 
			/// </summary>
			/// <returns> the conversion character.
			/// </returns>
			internal virtual char getConversionCharacter()
			{
				return conversionCharacter;
			}
			/// <summary> Format an int argument using this conversion
			/// specification.
			/// </summary>
			/// <param name="s">the int to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			/// <exception cref="IllegalArgumentException">if the
			/// conversion character is f, e, E, g, or G.
			/// </exception>
			internal virtual System.String internalsprintf(int s)
			{
				System.String s2 = "";
				switch (conversionCharacter)
				{
					
					case 'd': 
					case 'i': 
						if (optionalh)
							s2 = printDFormat((short) s);
						else if (optionall)
							s2 = printDFormat((long) s);
						else
							s2 = printDFormat(s);
						break;
					
					case 'x': 
					case 'X': 
						if (optionalh)
							s2 = printXFormat((short) s);
						else if (optionall)
							s2 = printXFormat((long) s);
						else
							s2 = printXFormat(s);
						break;
					
					case 'o': 
						if (optionalh)
							s2 = printOFormat((short) s);
						else if (optionall)
							s2 = printOFormat((long) s);
						else
							s2 = printOFormat(s);
						break;
					
					case 'c': 
					case 'C': 
						s2 = printCFormat((char) s);
						break;
					
					default: 
						throw new System.ArgumentException("Cannot format a int with a format using a " + conversionCharacter + " conversion character.");
					
				}
				return s2;
			}
			/// <summary> Format a long argument using this conversion
			/// specification.
			/// </summary>
			/// <param name="s">the long to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			/// <exception cref="IllegalArgumentException">if the
			/// conversion character is f, e, E, g, or G.
			/// </exception>
			internal virtual System.String internalsprintf(long s)
			{
				System.String s2 = "";
				switch (conversionCharacter)
				{
					
					case 'd': 
					case 'i': 
						if (optionalh)
							s2 = printDFormat((short) s);
						else if (optionall)
							s2 = printDFormat(s);
						else
							s2 = printDFormat((int) s);
						break;
					
					case 'x': 
					case 'X': 
						if (optionalh)
							s2 = printXFormat((short) s);
						else if (optionall)
							s2 = printXFormat(s);
						else
							s2 = printXFormat((int) s);
						break;
					
					case 'o': 
						if (optionalh)
							s2 = printOFormat((short) s);
						else if (optionall)
							s2 = printOFormat(s);
						else
							s2 = printOFormat((int) s);
						break;
					
					case 'c': 
					case 'C': 
						s2 = printCFormat((char) s);
						break;
					
					default: 
						throw new System.ArgumentException("Cannot format a long with a format using a " + conversionCharacter + " conversion character.");
					
				}
				return s2;
			}
			/// <summary> Format a double argument using this conversion
			/// specification.
			/// </summary>
			/// <param name="s">the double to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			/// <exception cref="IllegalArgumentException">if the
			/// conversion character is c, C, s, S, i, d,
			/// x, X, or o.
			/// </exception>
			internal virtual System.String internalsprintf(double s)
			{
				System.String s2 = "";
				switch (conversionCharacter)
				{
					
					case 'f': 
						s2 = printFFormat(s);
						break;
					
					case 'E': 
					case 'e': 
						s2 = printEFormat(s);
						break;
					
					case 'G': 
					case 'g': 
						s2 = printGFormat(s);
						break;
					
					default: 
						throw new System.ArgumentException("Cannot " + "format a double with a format using a " + conversionCharacter + " conversion character.");
					
				}
				return s2;
			}
			/// <summary> Format a String argument using this conversion
			/// specification.
			/// </summary>
			/// <param name="s">the String to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			/// <exception cref="IllegalArgumentException">if the
			/// conversion character is neither s nor S.
			/// </exception>
			internal virtual System.String internalsprintf(System.String s)
			{
				System.String s2 = "";
				if (conversionCharacter == 's' || conversionCharacter == 'S')
					s2 = printSFormat(s);
				else
					throw new System.ArgumentException("Cannot " + "format a String with a format using a " + conversionCharacter + " conversion character.");
				return s2;
			}
			/// <summary> Format an Object argument using this conversion
			/// specification.
			/// </summary>
			/// <param name="s">the Object to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			/// <exception cref="IllegalArgumentException">if the
			/// conversion character is neither s nor S.
			/// </exception>
			internal virtual System.String internalsprintf(System.Object s)
			{
				System.String s2 = "";
				if (conversionCharacter == 's' || conversionCharacter == 'S')
				{
					//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
					s2 = printSFormat(s.ToString());
				}
				else
					throw new System.ArgumentException("Cannot format a String with a format using" + " a " + conversionCharacter + " conversion character.");
				return s2;
			}
			/// <summary> For f format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both
			/// a '+' and a ' ' are specified, the blank flag
			/// is ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the number of digits
			/// to appear after the radix character.  Padding is
			/// with trailing 0s.
			/// </summary>
			private char[] fFormatDigits(double x)
			{
				// int defaultDigits=6;
				System.String sx, sxOut;
				int i, j, k;
				int n1In, n2In;
				int expon = 0;
				bool minusSign = false;
				if (x > 0.0)
					sx = x.ToString();
				else if (x < 0.0)
				{
					sx = (- x).ToString();
					minusSign = true;
				}
				else
				{
					sx = x.ToString();
					if (sx[0] == '-')
					{
						minusSign = true;
						sx = sx.Substring(1);
					}
				}
				int ePos = sx.IndexOf('E');
				int rPos = sx.IndexOf('.');
				if (rPos != - 1)
					n1In = rPos;
				else if (ePos != - 1)
					n1In = ePos;
				else
					n1In = sx.Length;
				if (rPos != - 1)
				{
					if (ePos != - 1)
						n2In = ePos - rPos - 1;
					else
						n2In = sx.Length - rPos - 1;
				}
				else
					n2In = 0;
				if (ePos != - 1)
				{
					int ie = ePos + 1;
					expon = 0;
					if (sx[ie] == '-')
					{
						for (++ie; ie < sx.Length; ie++)
							if (sx[ie] != '0')
								break;
						if (ie < sx.Length)
							expon = - System.Int32.Parse(sx.Substring(ie));
					}
					else
					{
						if (sx[ie] == '+')
							++ie;
						for (; ie < sx.Length; ie++)
							if (sx[ie] != '0')
								break;
						if (ie < sx.Length)
							expon = System.Int32.Parse(sx.Substring(ie));
					}
				}
				int p;
				if (precisionSet)
					p = precision;
				else
					p = defaultDigits - 1;
				char[] ca1 = sx.ToCharArray();
				char[] ca2 = new char[n1In + n2In];
				char[] ca3, ca4, ca5;
				for (j = 0; j < n1In; j++)
					ca2[j] = ca1[j];
				i = j + 1;
				for (k = 0; k < n2In; j++, i++, k++)
					ca2[j] = ca1[i];
				if (n1In + expon <= 0)
				{
					ca3 = new char[- expon + n2In];
					for (j = 0, k = 0; k < (- n1In - expon); k++, j++)
						ca3[j] = '0';
					for (i = 0; i < (n1In + n2In); i++, j++)
						ca3[j] = ca2[i];
				}
				else
					ca3 = ca2;
				bool carry = false;
				if (p < - expon + n2In)
				{
					if (expon < 0)
						i = p;
					else
						i = p + n1In;
					carry = checkForCarry(ca3, i);
					if (carry)
						carry = startSymbolicCarry(ca3, i - 1, 0);
				}
				if (n1In + expon <= 0)
				{
					ca4 = new char[2 + p];
					if (!carry)
						ca4[0] = '0';
					else
						ca4[0] = '1';
					if (alternateForm || !precisionSet || precision != 0)
					{
						ca4[1] = '.';
						for (i = 0, j = 2; i < System.Math.Min(p, ca3.Length); i++, j++)
							ca4[j] = ca3[i];
						for (; j < ca4.Length; j++)
							ca4[j] = '0';
					}
				}
				else
				{
					if (!carry)
					{
						if (alternateForm || !precisionSet || precision != 0)
							ca4 = new char[n1In + expon + p + 1];
						else
							ca4 = new char[n1In + expon];
						j = 0;
					}
					else
					{
						if (alternateForm || !precisionSet || precision != 0)
							ca4 = new char[n1In + expon + p + 2];
						else
							ca4 = new char[n1In + expon + 1];
						ca4[0] = '1';
						j = 1;
					}
					for (i = 0; i < System.Math.Min(n1In + expon, ca3.Length); i++, j++)
						ca4[j] = ca3[i];
					for (; i < n1In + expon; i++, j++)
						ca4[j] = '0';
					if (alternateForm || !precisionSet || precision != 0)
					{
						ca4[j] = '.';
						j++;
						for (k = 0; i < ca3.Length && k < p; i++, j++, k++)
							ca4[j] = ca3[i];
						for (; j < ca4.Length; j++)
							ca4[j] = '0';
					}
				}
				int nZeros = 0;
				if (!leftJustify && leadingZeros)
				{
					int xThousands = 0;
					if (thousands)
					{
						int xlead = 0;
						if (ca4[0] == '+' || ca4[0] == '-' || ca4[0] == ' ')
							xlead = 1;
						int xdp = xlead;
						for (; xdp < ca4.Length; xdp++)
							if (ca4[xdp] == '.')
								break;
						xThousands = (xdp - xlead) / 3;
					}
					if (fieldWidthSet)
						nZeros = fieldWidth - ca4.Length;
					if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
						nZeros--;
					nZeros -= xThousands;
					if (nZeros < 0)
						nZeros = 0;
				}
				j = 0;
				if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
				{
					ca5 = new char[ca4.Length + nZeros + 1];
					j++;
				}
				else
					ca5 = new char[ca4.Length + nZeros];
				if (!minusSign)
				{
					if (leadingSign)
						ca5[0] = '+';
					if (leadingSpace)
						ca5[0] = ' ';
				}
				else
					ca5[0] = '-';
				for (i = 0; i < nZeros; i++, j++)
					ca5[j] = '0';
				for (i = 0; i < ca4.Length; i++, j++)
					ca5[j] = ca4[i];
				
				int lead = 0;
				if (ca5[0] == '+' || ca5[0] == '-' || ca5[0] == ' ')
					lead = 1;
				int dp = lead;
				for (; dp < ca5.Length; dp++)
					if (ca5[dp] == '.')
						break;
				int nThousands = (dp - lead) / 3;
				// Localize the decimal point.
				if (dp < ca5.Length)
					ca5[dp] = Enclosing_Instance.dfs.NumberDecimalSeparator[0];
				char[] ca6 = ca5;
				if (thousands && nThousands > 0)
				{
					ca6 = new char[ca5.Length + nThousands + lead];
					ca6[0] = ca5[0];
					for (i = lead, k = lead; i < dp; i++)
					{
						if (i > 0 && (dp - i) % 3 == 0)
						{
							// ca6[k]=',';
							ca6[k] = Enclosing_Instance.dfs.NumberGroupSeparator[0];
							ca6[k + 1] = ca5[i];
							k += 2;
						}
						else
						{
							ca6[k] = ca5[i];
							k++;
						}
					}
					for (; i < ca5.Length; i++, k++)
					{
						ca6[k] = ca5[i];
					}
				}
				return ca6;
			}
			/// <summary> An intermediate routine on the way to creating
			/// an f format String.  The method decides whether
			/// the input double value is an infinity,
			/// not-a-number, or a finite double and formats
			/// each type of input appropriately.
			/// </summary>
			/// <param name="x">the double value to be formatted.
			/// </param>
			/// <returns> the converted double value.
			/// </returns>
			private System.String fFormatString(double x)
			{
				bool noDigits = false;
				char[] ca6, ca7;
				if (System.Double.IsInfinity(x))
				{
					if (x == System.Double.PositiveInfinity)
					{
						if (leadingSign)
							ca6 = "+Inf".ToCharArray();
						else if (leadingSpace)
							ca6 = " Inf".ToCharArray();
						else
							ca6 = "Inf".ToCharArray();
					}
					else
						ca6 = "-Inf".ToCharArray();
					noDigits = true;
				}
				else if (System.Double.IsNaN(x))
				{
					if (leadingSign)
						ca6 = "+NaN".ToCharArray();
					else if (leadingSpace)
						ca6 = " NaN".ToCharArray();
					else
						ca6 = "NaN".ToCharArray();
					noDigits = true;
				}
				else
					ca6 = fFormatDigits(x);
				ca7 = applyFloatPadding(ca6, false);
				return new System.String(ca7);
			}
			/// <summary> For e format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both a
			/// '+' and a ' ' are specified, the blank flag is
			/// ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear after the radix character.
			/// Padding is with trailing 0s.
			/// 
			/// The behavior is like printf.  One (hopefully the
			/// only) exception is that the minimum number of
			/// exponent digits is 3 instead of 2 for e and E
			/// formats when the optional L is used before the
			/// e, E, g, or G conversion character. The optional
			/// L does not imply conversion to a long long
			/// double.
			/// </summary>
			private char[] eFormatDigits(double x, char eChar)
			{
				char[] ca1, ca2, ca3;
				// int defaultDigits=6;
				System.String sx, sxOut;
				int i, j, k, p;
				int n1In, n2In;
				int expon = 0;
				int ePos, rPos, eSize;
				bool minusSign = false;
				if (x > 0.0)
					sx = x.ToString();
				else if (x < 0.0)
				{
					sx = (- x).ToString();
					minusSign = true;
				}
				else
				{
					sx = x.ToString();
					if (sx[0] == '-')
					{
						minusSign = true;
						sx = sx.Substring(1);
					}
				}
				ePos = sx.IndexOf('E');
				if (ePos == - 1)
					ePos = sx.IndexOf('e');
				rPos = sx.IndexOf('.');
				if (rPos != - 1)
					n1In = rPos;
				else if (ePos != - 1)
					n1In = ePos;
				else
					n1In = sx.Length;
				if (rPos != - 1)
				{
					if (ePos != - 1)
						n2In = ePos - rPos - 1;
					else
						n2In = sx.Length - rPos - 1;
				}
				else
					n2In = 0;
				if (ePos != - 1)
				{
					int ie = ePos + 1;
					expon = 0;
					if (sx[ie] == '-')
					{
						for (++ie; ie < sx.Length; ie++)
							if (sx[ie] != '0')
								break;
						if (ie < sx.Length)
							expon = - System.Int32.Parse(sx.Substring(ie));
					}
					else
					{
						if (sx[ie] == '+')
							++ie;
						for (; ie < sx.Length; ie++)
							if (sx[ie] != '0')
								break;
						if (ie < sx.Length)
							expon = System.Int32.Parse(sx.Substring(ie));
					}
				}
				if (rPos != - 1)
					expon += rPos - 1;
				if (precisionSet)
					p = precision;
				else
					p = defaultDigits - 1;
				if (rPos != - 1 && ePos != - 1)
					ca1 = (sx.Substring(0, (rPos) - (0)) + sx.Substring(rPos + 1, (ePos) - (rPos + 1))).ToCharArray();
				else if (rPos != - 1)
					ca1 = (sx.Substring(0, (rPos) - (0)) + sx.Substring(rPos + 1)).ToCharArray();
				else if (ePos != - 1)
					ca1 = sx.Substring(0, (ePos) - (0)).ToCharArray();
				else
					ca1 = sx.ToCharArray();
				bool carry = false;
				int i0 = 0;
				if (ca1[0] != '0')
					i0 = 0;
				else
					for (i0 = 0; i0 < ca1.Length; i0++)
						if (ca1[i0] != '0')
							break;
				if (i0 + p < ca1.Length - 1)
				{
					carry = checkForCarry(ca1, i0 + p + 1);
					if (carry)
						carry = startSymbolicCarry(ca1, i0 + p, i0);
					if (carry)
					{
						ca2 = new char[i0 + p + 1];
						ca2[i0] = '1';
						for (j = 0; j < i0; j++)
							ca2[j] = '0';
						for (i = i0, j = i0 + 1; j < p + 1; i++, j++)
							ca2[j] = ca1[i];
						expon++;
						ca1 = ca2;
					}
				}
				if (System.Math.Abs(expon) < 100 && !optionalL)
					eSize = 4;
				else
					eSize = 5;
				if (alternateForm || !precisionSet || precision != 0)
					ca2 = new char[2 + p + eSize];
				else
					ca2 = new char[1 + eSize];
				if (ca1[0] != '0')
				{
					ca2[0] = ca1[0];
					j = 1;
				}
				else
				{
					for (j = 1; j < (ePos == - 1?ca1.Length:ePos); j++)
						if (ca1[j] != '0')
							break;
					if ((ePos != - 1 && j < ePos) || (ePos == - 1 && j < ca1.Length))
					{
						ca2[0] = ca1[j];
						expon -= j;
						j++;
					}
					else
					{
						ca2[0] = '0';
						j = 2;
					}
				}
				if (alternateForm || !precisionSet || precision != 0)
				{
					ca2[1] = '.';
					i = 2;
				}
				else
					i = 1;
				for (k = 0; k < p && j < ca1.Length; j++, i++, k++)
					ca2[i] = ca1[j];
				for (; i < ca2.Length - eSize; i++)
					ca2[i] = '0';
				ca2[i++] = eChar;
				if (expon < 0)
					ca2[i++] = '-';
				else
					ca2[i++] = '+';
				expon = System.Math.Abs(expon);
				if (expon >= 100)
				{
					switch (expon / 100)
					{
						
						case 1: 
							ca2[i] = '1';
							break;
						
						case 2: 
							ca2[i] = '2';
							break;
						
						case 3: 
							ca2[i] = '3';
							break;
						
						case 4: 
							ca2[i] = '4';
							break;
						
						case 5: 
							ca2[i] = '5';
							break;
						
						case 6: 
							ca2[i] = '6';
							break;
						
						case 7: 
							ca2[i] = '7';
							break;
						
						case 8: 
							ca2[i] = '8';
							break;
						
						case 9: 
							ca2[i] = '9';
							break;
						}
					i++;
				}
				switch ((expon % 100) / 10)
				{
					
					case 0: 
						ca2[i] = '0';
						break;
					
					case 1: 
						ca2[i] = '1';
						break;
					
					case 2: 
						ca2[i] = '2';
						break;
					
					case 3: 
						ca2[i] = '3';
						break;
					
					case 4: 
						ca2[i] = '4';
						break;
					
					case 5: 
						ca2[i] = '5';
						break;
					
					case 6: 
						ca2[i] = '6';
						break;
					
					case 7: 
						ca2[i] = '7';
						break;
					
					case 8: 
						ca2[i] = '8';
						break;
					
					case 9: 
						ca2[i] = '9';
						break;
					}
				i++;
				switch (expon % 10)
				{
					
					case 0: 
						ca2[i] = '0';
						break;
					
					case 1: 
						ca2[i] = '1';
						break;
					
					case 2: 
						ca2[i] = '2';
						break;
					
					case 3: 
						ca2[i] = '3';
						break;
					
					case 4: 
						ca2[i] = '4';
						break;
					
					case 5: 
						ca2[i] = '5';
						break;
					
					case 6: 
						ca2[i] = '6';
						break;
					
					case 7: 
						ca2[i] = '7';
						break;
					
					case 8: 
						ca2[i] = '8';
						break;
					
					case 9: 
						ca2[i] = '9';
						break;
					}
				int nZeros = 0;
				if (!leftJustify && leadingZeros)
				{
					int xThousands = 0;
					if (thousands)
					{
						int xlead = 0;
						if (ca2[0] == '+' || ca2[0] == '-' || ca2[0] == ' ')
							xlead = 1;
						int xdp = xlead;
						for (; xdp < ca2.Length; xdp++)
							if (ca2[xdp] == '.')
								break;
						xThousands = (xdp - xlead) / 3;
					}
					if (fieldWidthSet)
						nZeros = fieldWidth - ca2.Length;
					if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
						nZeros--;
					nZeros -= xThousands;
					if (nZeros < 0)
						nZeros = 0;
				}
				j = 0;
				if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
				{
					ca3 = new char[ca2.Length + nZeros + 1];
					j++;
				}
				else
					ca3 = new char[ca2.Length + nZeros];
				if (!minusSign)
				{
					if (leadingSign)
						ca3[0] = '+';
					if (leadingSpace)
						ca3[0] = ' ';
				}
				else
					ca3[0] = '-';
				for (k = 0; k < nZeros; j++, k++)
					ca3[j] = '0';
				for (i = 0; i < ca2.Length && j < ca3.Length; i++, j++)
					ca3[j] = ca2[i];
				
				int lead = 0;
				if (ca3[0] == '+' || ca3[0] == '-' || ca3[0] == ' ')
					lead = 1;
				int dp = lead;
				for (; dp < ca3.Length; dp++)
					if (ca3[dp] == '.')
						break;
				int nThousands = dp / 3;
				// Localize the decimal point.
				if (dp < ca3.Length)
					ca3[dp] = Enclosing_Instance.dfs.NumberDecimalSeparator[0];
				char[] ca4 = ca3;
				if (thousands && nThousands > 0)
				{
					ca4 = new char[ca3.Length + nThousands + lead];
					ca4[0] = ca3[0];
					for (i = lead, k = lead; i < dp; i++)
					{
						if (i > 0 && (dp - i) % 3 == 0)
						{
							// ca4[k]=',';
							ca4[k] = Enclosing_Instance.dfs.NumberGroupSeparator[0];
							ca4[k + 1] = ca3[i];
							k += 2;
						}
						else
						{
							ca4[k] = ca3[i];
							k++;
						}
					}
					for (; i < ca3.Length; i++, k++)
						ca4[k] = ca3[i];
				}
				return ca4;
			}
			/// <summary> Check to see if the digits that are going to
			/// be truncated because of the precision should
			/// force a round in the preceding digits.
			/// </summary>
			/// <param name="ca1">the array of digits
			/// </param>
			/// <param name="icarry">the index of the first digit that
			/// is to be truncated from the print
			/// </param>
			/// <returns> <code>true</code> if the truncation forces
			/// a round that will change the print
			/// </returns>
			private bool checkForCarry(char[] ca1, int icarry)
			{
				bool carry = false;
				if (icarry < ca1.Length)
				{
					if (ca1[icarry] == '6' || ca1[icarry] == '7' || ca1[icarry] == '8' || ca1[icarry] == '9')
						carry = true;
					else if (ca1[icarry] == '5')
					{
						int ii = icarry + 1;
						for (; ii < ca1.Length; ii++)
							if (ca1[ii] != '0')
								break;
						carry = ii < ca1.Length;
						if (!carry && icarry > 0)
						{
							carry = (ca1[icarry - 1] == '1' || ca1[icarry - 1] == '3' || ca1[icarry - 1] == '5' || ca1[icarry - 1] == '7' || ca1[icarry - 1] == '9');
						}
					}
				}
				return carry;
			}
			/// <summary> Start the symbolic carry process.  The process
			/// is not quite finished because the symbolic
			/// carry may change the length of the string and
			/// change the exponent (in e format).
			/// </summary>
			/// <param name="cLast">index of the last digit changed
			/// by the round
			/// </param>
			/// <param name="cFirst">index of the first digit allowed
			/// to be changed by this phase of the round
			/// </param>
			/// <returns> <code>true</code> if the carry forces
			/// a round that will change the print still
			/// more
			/// </returns>
			private bool startSymbolicCarry(char[] ca, int cLast, int cFirst)
			{
				bool carry = true;
				for (int i = cLast; carry && i >= cFirst; i--)
				{
					carry = false;
					switch (ca[i])
					{
						
						case '0': 
							ca[i] = '1';
							break;
						
						case '1': 
							ca[i] = '2';
							break;
						
						case '2': 
							ca[i] = '3';
							break;
						
						case '3': 
							ca[i] = '4';
							break;
						
						case '4': 
							ca[i] = '5';
							break;
						
						case '5': 
							ca[i] = '6';
							break;
						
						case '6': 
							ca[i] = '7';
							break;
						
						case '7': 
							ca[i] = '8';
							break;
						
						case '8': 
							ca[i] = '9';
							break;
						
						case '9': 
							ca[i] = '0';
							carry = true;
							break;
						}
				}
				return carry;
			}
			/// <summary> An intermediate routine on the way to creating
			/// an e format String.  The method decides whether
			/// the input double value is an infinity,
			/// not-a-number, or a finite double and formats
			/// each type of input appropriately.
			/// </summary>
			/// <param name="x">the double value to be formatted.
			/// </param>
			/// <param name="eChar">an 'e' or 'E' to use in the
			/// converted double value.
			/// </param>
			/// <returns> the converted double value.
			/// </returns>
			private System.String eFormatString(double x, char eChar)
			{
				bool noDigits = false;
				char[] ca4, ca5;
				if (System.Double.IsInfinity(x))
				{
					if (x == System.Double.PositiveInfinity)
					{
						if (leadingSign)
							ca4 = "+Inf".ToCharArray();
						else if (leadingSpace)
							ca4 = " Inf".ToCharArray();
						else
							ca4 = "Inf".ToCharArray();
					}
					else
						ca4 = "-Inf".ToCharArray();
					noDigits = true;
				}
				else if (System.Double.IsNaN(x))
				{
					if (leadingSign)
						ca4 = "+NaN".ToCharArray();
					else if (leadingSpace)
						ca4 = " NaN".ToCharArray();
					else
						ca4 = "NaN".ToCharArray();
					noDigits = true;
				}
				else
					ca4 = eFormatDigits(x, eChar);
				ca5 = applyFloatPadding(ca4, false);
				return new System.String(ca5);
			}
			/// <summary> Apply zero or blank, left or right padding.</summary>
			/// <param name="ca4">array of characters before padding is
			/// finished
			/// </param>
			/// <param name="noDigits">NaN or signed Inf
			/// </param>
			/// <returns> a padded array of characters
			/// </returns>
			private char[] applyFloatPadding(char[] ca4, bool noDigits)
			{
				char[] ca5 = ca4;
				if (fieldWidthSet)
				{
					int i, j, nBlanks;
					if (leftJustify)
					{
						nBlanks = fieldWidth - ca4.Length;
						if (nBlanks > 0)
						{
							ca5 = new char[ca4.Length + nBlanks];
							for (i = 0; i < ca4.Length; i++)
								ca5[i] = ca4[i];
							for (j = 0; j < nBlanks; j++, i++)
								ca5[i] = ' ';
						}
					}
					else if (!leadingZeros || noDigits)
					{
						nBlanks = fieldWidth - ca4.Length;
						if (nBlanks > 0)
						{
							ca5 = new char[ca4.Length + nBlanks];
							for (i = 0; i < nBlanks; i++)
								ca5[i] = ' ';
							for (j = 0; j < ca4.Length; i++, j++)
								ca5[i] = ca4[j];
						}
					}
					else if (leadingZeros)
					{
						nBlanks = fieldWidth - ca4.Length;
						if (nBlanks > 0)
						{
							ca5 = new char[ca4.Length + nBlanks];
							i = 0;
							j = 0;
							if (ca4[0] == '-')
							{
								ca5[0] = '-';
								i++;
								j++;
							}
							for (int k = 0; k < nBlanks; i++, k++)
								ca5[i] = '0';
							for (; j < ca4.Length; i++, j++)
								ca5[i] = ca4[j];
						}
					}
				}
				return ca5;
			}
			/// <summary> Format method for the f conversion character.</summary>
			/// <param name="x">the double to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printFFormat(double x)
			{
				return fFormatString(x);
			}
			/// <summary> Format method for the e or E conversion
			/// character.
			/// </summary>
			/// <param name="x">the double to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printEFormat(double x)
			{
				if (conversionCharacter == 'e')
					return eFormatString(x, 'e');
				else
					return eFormatString(x, 'E');
			}
			/// <summary> Format method for the g conversion character.
			/// 
			/// For g format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both a
			/// '+' and a ' ' are specified, the blank flag is
			/// ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear after the radix character.
			/// Padding is with trailing 0s.
			/// </summary>
			/// <param name="x">the double to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printGFormat(double x)
			{
				System.String sx, sy, sz, ret;
				int savePrecision = precision;
				int i;
				char[] ca4, ca5;
				bool noDigits = false;
				if (System.Double.IsInfinity(x))
				{
					if (x == System.Double.PositiveInfinity)
					{
						if (leadingSign)
							ca4 = "+Inf".ToCharArray();
						else if (leadingSpace)
							ca4 = " Inf".ToCharArray();
						else
							ca4 = "Inf".ToCharArray();
					}
					else
						ca4 = "-Inf".ToCharArray();
					noDigits = true;
				}
				else if (System.Double.IsNaN(x))
				{
					if (leadingSign)
						ca4 = "+NaN".ToCharArray();
					else if (leadingSpace)
						ca4 = " NaN".ToCharArray();
					else
						ca4 = "NaN".ToCharArray();
					noDigits = true;
				}
				else
				{
					if (!precisionSet)
						precision = defaultDigits;
					if (precision == 0)
						precision = 1;
					int ePos = - 1;
					if (conversionCharacter == 'g')
					{
						sx = eFormatString(x, 'e').Trim();
						ePos = sx.IndexOf('e');
					}
					else
					{
						sx = eFormatString(x, 'E').Trim();
						ePos = sx.IndexOf('E');
					}
					i = ePos + 1;
					int expon = 0;
					if (sx[i] == '-')
					{
						for (++i; i < sx.Length; i++)
							if (sx[i] != '0')
								break;
						if (i < sx.Length)
							expon = - System.Int32.Parse(sx.Substring(i));
					}
					else
					{
						if (sx[i] == '+')
							++i;
						for (; i < sx.Length; i++)
							if (sx[i] != '0')
								break;
						if (i < sx.Length)
							expon = System.Int32.Parse(sx.Substring(i));
					}
					// Trim trailing zeros.
					// If the radix character is not followed by
					// a digit, trim it, too.
					if (!alternateForm)
					{
						if (expon >= - 4 && expon < precision)
							sy = fFormatString(x).Trim();
						else
							sy = sx.Substring(0, (ePos) - (0));
						i = sy.Length - 1;
						for (; i >= 0; i--)
							if (sy[i] != '0')
								break;
						if (i >= 0 && sy[i] == '.')
							i--;
						if (i == - 1)
							sz = "0";
						else if (!System.Char.IsDigit(sy[i]))
							sz = sy.Substring(0, (i + 1) - (0)) + "0";
						else
							sz = sy.Substring(0, (i + 1) - (0));
						if (expon >= - 4 && expon < precision)
							ret = sz;
						else
							ret = sz + sx.Substring(ePos);
					}
					else
					{
						if (expon >= - 4 && expon < precision)
							ret = fFormatString(x).Trim();
						else
							ret = sx;
					}
					// leading space was trimmed off during
					// construction
					if (leadingSpace)
						if (x >= 0)
							ret = " " + ret;
					ca4 = ret.ToCharArray();
				}
				// Pad with blanks or zeros.
				ca5 = applyFloatPadding(ca4, false);
				precision = savePrecision;
				return new System.String(ca5);
			}
			/// <summary> Format method for the d conversion specifer and
			/// short argument.
			/// 
			/// For d format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  A '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both a
			/// '+' and a ' ' are specified, the blank flag is
			/// ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the short to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printDFormat(short x)
			{
				return printDFormat(x.ToString());
			}
			/// <summary> Format method for the d conversion character and
			/// long argument.
			/// 
			/// For d format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  A '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both a
			/// '+' and a ' ' are specified, the blank flag is
			/// ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the long to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printDFormat(long x)
			{
				return printDFormat(System.Convert.ToString(x));
			}
			/// <summary> Format method for the d conversion character and
			/// int argument.
			/// 
			/// For d format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  A '+' character means that the conversion
			/// will always begin with a sign (+ or -).  The
			/// blank flag character means that a non-negative
			/// input will be preceded with a blank.  If both a
			/// '+' and a ' ' are specified, the blank flag is
			/// ignored.  The '0' flag character implies that
			/// padding to the field width will be done with
			/// zeros instead of blanks.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the int to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printDFormat(int x)
			{
				return printDFormat(System.Convert.ToString(x));
			}
			/// <summary> Utility method for formatting using the d
			/// conversion character.
			/// </summary>
			/// <param name="sx">the String to format, the result of
			/// converting a short, int, or long to a
			/// String.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printDFormat(System.String sx)
			{
				int nLeadingZeros = 0;
				int nBlanks = 0, n = 0;
				int i = 0, jFirst = 0;
				bool neg = sx[0] == '-';
				if (sx.Equals("0") && precisionSet && precision == 0)
					sx = "";
				if (!neg)
				{
					if (precisionSet && sx.Length < precision)
						nLeadingZeros = precision - sx.Length;
				}
				else
				{
					if (precisionSet && (sx.Length - 1) < precision)
						nLeadingZeros = precision - sx.Length + 1;
				}
				if (nLeadingZeros < 0)
					nLeadingZeros = 0;
				if (fieldWidthSet)
				{
					nBlanks = fieldWidth - nLeadingZeros - sx.Length;
					if (!neg && (leadingSign || leadingSpace))
						nBlanks--;
				}
				if (nBlanks < 0)
					nBlanks = 0;
				if (leadingSign)
					n++;
				else if (leadingSpace)
					n++;
				n += nBlanks;
				n += nLeadingZeros;
				n += sx.Length;
				char[] ca = new char[n];
				if (leftJustify)
				{
					if (neg)
						ca[i++] = '-';
					else if (leadingSign)
						ca[i++] = '+';
					else if (leadingSpace)
						ca[i++] = ' ';
					char[] csx = sx.ToCharArray();
					jFirst = neg?1:0;
					for (int j = 0; j < nLeadingZeros; i++, j++)
						ca[i] = '0';
					for (int j = jFirst; j < csx.Length; j++, i++)
						ca[i] = csx[j];
					for (int j = 0; j < nBlanks; i++, j++)
						ca[i] = ' ';
				}
				else
				{
					if (!leadingZeros)
					{
						for (i = 0; i < nBlanks; i++)
							ca[i] = ' ';
						if (neg)
							ca[i++] = '-';
						else if (leadingSign)
							ca[i++] = '+';
						else if (leadingSpace)
							ca[i++] = ' ';
					}
					else
					{
						if (neg)
							ca[i++] = '-';
						else if (leadingSign)
							ca[i++] = '+';
						else if (leadingSpace)
							ca[i++] = ' ';
						for (int j = 0; j < nBlanks; j++, i++)
							ca[i] = '0';
					}
					for (int j = 0; j < nLeadingZeros; j++, i++)
						ca[i] = '0';
					char[] csx = sx.ToCharArray();
					jFirst = neg?1:0;
					for (int j = jFirst; j < csx.Length; j++, i++)
						ca[i] = csx[j];
				}
				return new System.String(ca);
			}
			/// <summary> Format method for the x conversion character and
			/// short argument.
			/// 
			/// For x format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  The '#' flag character means to lead with
			/// '0x'.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the short to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printXFormat(short x)
			{
				System.String sx = null;
				if (x == System.Int16.MinValue)
					sx = "8000";
				else if (x < 0)
				{
					System.String t;
					if (x == System.Int16.MinValue)
						t = "0";
					else
					{
						t = System.Convert.ToString((~ (- x - 1)) ^ System.Int16.MinValue, 16);
						if (t[0] == 'F' || t[0] == 'f')
							t = t.Substring(16, (32) - (16));
					}
					switch (t.Length)
					{
						
						case 1: 
							sx = "800" + t;
							break;
						
						case 2: 
							sx = "80" + t;
							break;
						
						case 3: 
							sx = "8" + t;
							break;
						
						case 4: 
							switch (t[0])
							{
								
								case '1': 
									sx = "9" + t.Substring(1, (4) - (1));
									break;
								
								case '2': 
									sx = "a" + t.Substring(1, (4) - (1));
									break;
								
								case '3': 
									sx = "b" + t.Substring(1, (4) - (1));
									break;
								
								case '4': 
									sx = "c" + t.Substring(1, (4) - (1));
									break;
								
								case '5': 
									sx = "d" + t.Substring(1, (4) - (1));
									break;
								
								case '6': 
									sx = "e" + t.Substring(1, (4) - (1));
									break;
								
								case '7': 
									sx = "f" + t.Substring(1, (4) - (1));
									break;
								}
							break;
						}
				}
				else
					sx = System.Convert.ToString((int) x, 16);
				return printXFormat(sx);
			}
			/// <summary> Format method for the x conversion character and
			/// long argument.
			/// 
			/// For x format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  The '#' flag character means to lead with
			/// '0x'.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the long to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printXFormat(long x)
			{
				System.String sx = null;
				if (x == System.Int64.MinValue)
					sx = "8000000000000000";
				else if (x < 0)
				{
					System.String t = System.Convert.ToString((~ (- x - 1)) ^ System.Int64.MinValue, 16);
					switch (t.Length)
					{
						
						case 1: 
							sx = "800000000000000" + t;
							break;
						
						case 2: 
							sx = "80000000000000" + t;
							break;
						
						case 3: 
							sx = "8000000000000" + t;
							break;
						
						case 4: 
							sx = "800000000000" + t;
							break;
						
						case 5: 
							sx = "80000000000" + t;
							break;
						
						case 6: 
							sx = "8000000000" + t;
							break;
						
						case 7: 
							sx = "800000000" + t;
							break;
						
						case 8: 
							sx = "80000000" + t;
							break;
						
						case 9: 
							sx = "8000000" + t;
							break;
						
						case 10: 
							sx = "800000" + t;
							break;
						
						case 11: 
							sx = "80000" + t;
							break;
						
						case 12: 
							sx = "8000" + t;
							break;
						
						case 13: 
							sx = "800" + t;
							break;
						
						case 14: 
							sx = "80" + t;
							break;
						
						case 15: 
							sx = "8" + t;
							break;
						
						case 16: 
							switch (t[0])
							{
								
								case '1': 
									sx = "9" + t.Substring(1, (16) - (1));
									break;
								
								case '2': 
									sx = "a" + t.Substring(1, (16) - (1));
									break;
								
								case '3': 
									sx = "b" + t.Substring(1, (16) - (1));
									break;
								
								case '4': 
									sx = "c" + t.Substring(1, (16) - (1));
									break;
								
								case '5': 
									sx = "d" + t.Substring(1, (16) - (1));
									break;
								
								case '6': 
									sx = "e" + t.Substring(1, (16) - (1));
									break;
								
								case '7': 
									sx = "f" + t.Substring(1, (16) - (1));
									break;
								}
							break;
						}
				}
				else
					sx = System.Convert.ToString(x, 16);
				return printXFormat(sx);
			}
			/// <summary> Format method for the x conversion character and
			/// int argument.
			/// 
			/// For x format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  The '#' flag character means to lead with
			/// '0x'.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the int to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printXFormat(int x)
			{
				System.String sx = null;
				if (x == System.Int32.MinValue)
					sx = "80000000";
				else if (x < 0)
				{
					System.String t = System.Convert.ToString((~ (- x - 1)) ^ System.Int32.MinValue, 16);
					switch (t.Length)
					{
						
						case 1: 
							sx = "8000000" + t;
							break;
						
						case 2: 
							sx = "800000" + t;
							break;
						
						case 3: 
							sx = "80000" + t;
							break;
						
						case 4: 
							sx = "8000" + t;
							break;
						
						case 5: 
							sx = "800" + t;
							break;
						
						case 6: 
							sx = "80" + t;
							break;
						
						case 7: 
							sx = "8" + t;
							break;
						
						case 8: 
							switch (t[0])
							{
								
								case '1': 
									sx = "9" + t.Substring(1, (8) - (1));
									break;
								
								case '2': 
									sx = "a" + t.Substring(1, (8) - (1));
									break;
								
								case '3': 
									sx = "b" + t.Substring(1, (8) - (1));
									break;
								
								case '4': 
									sx = "c" + t.Substring(1, (8) - (1));
									break;
								
								case '5': 
									sx = "d" + t.Substring(1, (8) - (1));
									break;
								
								case '6': 
									sx = "e" + t.Substring(1, (8) - (1));
									break;
								
								case '7': 
									sx = "f" + t.Substring(1, (8) - (1));
									break;
								}
							break;
						}
				}
				else
					sx = System.Convert.ToString(x, 16);
				return printXFormat(sx);
			}
			/// <summary> Utility method for formatting using the x
			/// conversion character.
			/// </summary>
			/// <param name="sx">the String to format, the result of
			/// converting a short, int, or long to a
			/// String.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printXFormat(System.String sx)
			{
				int nLeadingZeros = 0;
				int nBlanks = 0;
				if (sx.Equals("0") && precisionSet && precision == 0)
					sx = "";
				if (precisionSet)
					nLeadingZeros = precision - sx.Length;
				if (nLeadingZeros < 0)
					nLeadingZeros = 0;
				if (fieldWidthSet)
				{
					nBlanks = fieldWidth - nLeadingZeros - sx.Length;
					if (alternateForm)
						nBlanks = nBlanks - 2;
				}
				if (nBlanks < 0)
					nBlanks = 0;
				int n = 0;
				if (alternateForm)
					n += 2;
				n += nLeadingZeros;
				n += sx.Length;
				n += nBlanks;
				char[] ca = new char[n];
				int i = 0;
				if (leftJustify)
				{
					if (alternateForm)
					{
						ca[i++] = '0';
						ca[i++] = 'x';
					}
					for (int j = 0; j < nLeadingZeros; j++, i++)
						ca[i] = '0';
					char[] csx = sx.ToCharArray();
					for (int j = 0; j < csx.Length; j++, i++)
						ca[i] = csx[j];
					for (int j = 0; j < nBlanks; j++, i++)
						ca[i] = ' ';
				}
				else
				{
					if (!leadingZeros)
						for (int j = 0; j < nBlanks; j++, i++)
							ca[i] = ' ';
					if (alternateForm)
					{
						ca[i++] = '0';
						ca[i++] = 'x';
					}
					if (leadingZeros)
						for (int j = 0; j < nBlanks; j++, i++)
							ca[i] = '0';
					for (int j = 0; j < nLeadingZeros; j++, i++)
						ca[i] = '0';
					char[] csx = sx.ToCharArray();
					for (int j = 0; j < csx.Length; j++, i++)
						ca[i] = csx[j];
				}
				System.String caReturn = new System.String(ca);
				if (conversionCharacter == 'X')
					caReturn = caReturn.ToUpper();
				return caReturn;
			}
			/// <summary> Format method for the o conversion character and
			/// short argument.
			/// 
			/// For o format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the 
			/// left.  The '#' flag character means that the
			/// output begins with a leading 0 and the precision
			/// is increased by 1.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the short to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printOFormat(short x)
			{
				System.String sx = null;
				if (x == System.Int16.MinValue)
					sx = "100000";
				else if (x < 0)
				{
					System.String t = System.Convert.ToString((~ (- x - 1)) ^ System.Int16.MinValue, 8);
					switch (t.Length)
					{
						
						case 1: 
							sx = "10000" + t;
							break;
						
						case 2: 
							sx = "1000" + t;
							break;
						
						case 3: 
							sx = "100" + t;
							break;
						
						case 4: 
							sx = "10" + t;
							break;
						
						case 5: 
							sx = "1" + t;
							break;
						}
				}
				else
					sx = System.Convert.ToString((int) x, 8);
				return printOFormat(sx);
			}
			/// <summary> Format method for the o conversion character and
			/// long argument.
			/// 
			/// For o format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the 
			/// left.  The '#' flag character means that the
			/// output begins with a leading 0 and the precision
			/// is increased by 1.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the long to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printOFormat(long x)
			{
				System.String sx = null;
				if (x == System.Int64.MinValue)
					sx = "1000000000000000000000";
				else if (x < 0)
				{
					System.String t = System.Convert.ToString((~ (- x - 1)) ^ System.Int64.MinValue, 8);
					switch (t.Length)
					{
						
						case 1: 
							sx = "100000000000000000000" + t;
							break;
						
						case 2: 
							sx = "10000000000000000000" + t;
							break;
						
						case 3: 
							sx = "1000000000000000000" + t;
							break;
						
						case 4: 
							sx = "100000000000000000" + t;
							break;
						
						case 5: 
							sx = "10000000000000000" + t;
							break;
						
						case 6: 
							sx = "1000000000000000" + t;
							break;
						
						case 7: 
							sx = "100000000000000" + t;
							break;
						
						case 8: 
							sx = "10000000000000" + t;
							break;
						
						case 9: 
							sx = "1000000000000" + t;
							break;
						
						case 10: 
							sx = "100000000000" + t;
							break;
						
						case 11: 
							sx = "10000000000" + t;
							break;
						
						case 12: 
							sx = "1000000000" + t;
							break;
						
						case 13: 
							sx = "100000000" + t;
							break;
						
						case 14: 
							sx = "10000000" + t;
							break;
						
						case 15: 
							sx = "1000000" + t;
							break;
						
						case 16: 
							sx = "100000" + t;
							break;
						
						case 17: 
							sx = "10000" + t;
							break;
						
						case 18: 
							sx = "1000" + t;
							break;
						
						case 19: 
							sx = "100" + t;
							break;
						
						case 20: 
							sx = "10" + t;
							break;
						
						case 21: 
							sx = "1" + t;
							break;
						}
				}
				else
					sx = System.Convert.ToString(x, 8);
				return printOFormat(sx);
			}
			/// <summary> Format method for the o conversion character and
			/// int argument.
			/// 
			/// For o format, the flag character '-', means that
			/// the output should be left justified within the
			/// field.  The default is to pad with blanks on the
			/// left.  The '#' flag character means that the
			/// output begins with a leading 0 and the precision
			/// is increased by 1.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is to
			/// add no padding.  Padding is with blanks by
			/// default.
			/// 
			/// The precision, if set, is the minimum number of
			/// digits to appear.  Padding is with leading 0s.
			/// </summary>
			/// <param name="x">the int to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printOFormat(int x)
			{
				System.String sx = null;
				if (x == System.Int32.MinValue)
					sx = "20000000000";
				else if (x < 0)
				{
					System.String t = System.Convert.ToString((~ (- x - 1)) ^ System.Int32.MinValue, 8);
					switch (t.Length)
					{
						
						case 1: 
							sx = "2000000000" + t;
							break;
						
						case 2: 
							sx = "200000000" + t;
							break;
						
						case 3: 
							sx = "20000000" + t;
							break;
						
						case 4: 
							sx = "2000000" + t;
							break;
						
						case 5: 
							sx = "200000" + t;
							break;
						
						case 6: 
							sx = "20000" + t;
							break;
						
						case 7: 
							sx = "2000" + t;
							break;
						
						case 8: 
							sx = "200" + t;
							break;
						
						case 9: 
							sx = "20" + t;
							break;
						
						case 10: 
							sx = "2" + t;
							break;
						
						case 11: 
							sx = "3" + t.Substring(1);
							break;
						}
				}
				else
					sx = System.Convert.ToString(x, 8);
				return printOFormat(sx);
			}
			/// <summary> Utility method for formatting using the o
			/// conversion character.
			/// </summary>
			/// <param name="sx">the String to format, the result of
			/// converting a short, int, or long to a
			/// String.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printOFormat(System.String sx)
			{
				int nLeadingZeros = 0;
				int nBlanks = 0;
				if (sx.Equals("0") && precisionSet && precision == 0)
					sx = "";
				if (precisionSet)
					nLeadingZeros = precision - sx.Length;
				if (alternateForm)
					nLeadingZeros++;
				if (nLeadingZeros < 0)
					nLeadingZeros = 0;
				if (fieldWidthSet)
					nBlanks = fieldWidth - nLeadingZeros - sx.Length;
				if (nBlanks < 0)
					nBlanks = 0;
				int n = nLeadingZeros + sx.Length + nBlanks;
				char[] ca = new char[n];
				int i;
				if (leftJustify)
				{
					for (i = 0; i < nLeadingZeros; i++)
						ca[i] = '0';
					char[] csx = sx.ToCharArray();
					for (int j = 0; j < csx.Length; j++, i++)
						ca[i] = csx[j];
					for (int j = 0; j < nBlanks; j++, i++)
						ca[i] = ' ';
				}
				else
				{
					if (leadingZeros)
						for (i = 0; i < nBlanks; i++)
							ca[i] = '0';
					else
						for (i = 0; i < nBlanks; i++)
							ca[i] = ' ';
					for (int j = 0; j < nLeadingZeros; j++, i++)
						ca[i] = '0';
					char[] csx = sx.ToCharArray();
					for (int j = 0; j < csx.Length; j++, i++)
						ca[i] = csx[j];
				}
				return new System.String(ca);
			}
			/// <summary> Format method for the c conversion character and
			/// char argument.
			/// 
			/// The only flag character that affects c format is
			/// the '-', meaning that the output should be left
			/// justified within the field.  The default is to
			/// pad with blanks on the left.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  Padding is with
			/// blanks by default.  The default width is 1.
			/// 
			/// The precision, if set, is ignored.
			/// </summary>
			/// <param name="x">the char to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printCFormat(char x)
			{
				int nPrint = 1;
				int width = fieldWidth;
				if (!fieldWidthSet)
					width = nPrint;
				char[] ca = new char[width];
				int i = 0;
				if (leftJustify)
				{
					ca[0] = x;
					for (i = 1; i <= width - nPrint; i++)
						ca[i] = ' ';
				}
				else
				{
					for (i = 0; i < width - nPrint; i++)
						ca[i] = ' ';
					ca[i] = x;
				}
				return new System.String(ca);
			}
			/// <summary> Format method for the s conversion character and
			/// String argument.
			/// 
			/// The only flag character that affects s format is
			/// the '-', meaning that the output should be left
			/// justified within the field.  The default is to
			/// pad with blanks on the left.
			/// 
			/// The field width is treated as the minimum number
			/// of characters to be printed.  The default is the
			/// smaller of the number of characters in the the
			/// input and the precision.  Padding is with blanks
			/// by default.
			/// 
			/// The precision, if set, specifies the maximum
			/// number of characters to be printed from the
			/// string.  A null digit string is treated
			/// as a 0.  The default is not to set a maximum
			/// number of characters to be printed.
			/// </summary>
			/// <param name="x">the String to format.
			/// </param>
			/// <returns> the formatted String.
			/// </returns>
			private System.String printSFormat(System.String x)
			{
				int nPrint = x.Length;
				int width = fieldWidth;
				if (precisionSet && nPrint > precision)
					nPrint = precision;
				if (!fieldWidthSet)
					width = nPrint;
				int n = 0;
				if (width > nPrint)
					n += width - nPrint;
				if (nPrint >= x.Length)
					n += x.Length;
				else
					n += nPrint;
				char[] ca = new char[n];
				int i = 0;
				if (leftJustify)
				{
					if (nPrint >= x.Length)
					{
						char[] csx = x.ToCharArray();
						for (i = 0; i < x.Length; i++)
							ca[i] = csx[i];
					}
					else
					{
						char[] csx = x.Substring(0, (nPrint) - (0)).ToCharArray();
						for (i = 0; i < nPrint; i++)
							ca[i] = csx[i];
					}
					for (int j = 0; j < width - nPrint; j++, i++)
						ca[i] = ' ';
				}
				else
				{
					for (i = 0; i < width - nPrint; i++)
						ca[i] = ' ';
					if (nPrint >= x.Length)
					{
						char[] csx = x.ToCharArray();
						for (int j = 0; j < x.Length; i++, j++)
							ca[i] = csx[j];
					}
					else
					{
						char[] csx = x.Substring(0, (nPrint) - (0)).ToCharArray();
						for (int j = 0; j < nPrint; i++, j++)
							ca[i] = csx[j];
					}
				}
				return new System.String(ca);
			}
			/// <summary> Check for a conversion character.  If it is
			/// there, store it.
			/// </summary>
			/// <param name="x">the String to format.
			/// </param>
			/// <returns> <code>true</code> if the conversion
			/// character is there, and
			/// <code>false</code> otherwise.
			/// </returns>
			private bool setConversionCharacter()
			{
				/* idfgGoxXeEcs */
				bool ret = false;
				conversionCharacter = '\x0000';
				if (pos < fmt.Length)
				{
					char c = fmt[pos];
					if (c == 'i' || c == 'd' || c == 'f' || c == 'g' || c == 'G' || c == 'o' || c == 'x' || c == 'X' || c == 'e' || c == 'E' || c == 'c' || c == 's' || c == '%')
					{
						conversionCharacter = c;
						pos++;
						ret = true;
					}
				}
				return ret;
			}
			/// <summary> Check for an h, l, or L in a format.  An L is
			/// used to control the minimum number of digits
			/// in an exponent when using floating point
			/// formats.  An l or h is used to control
			/// conversion of the input to a long or short,
			/// respectively, before formatting.  If any of
			/// these is present, store them.
			/// </summary>
			private void  setOptionalHL()
			{
				optionalh = false;
				optionall = false;
				optionalL = false;
				if (pos < fmt.Length)
				{
					char c = fmt[pos];
					if (c == 'h')
					{
						optionalh = true;
						pos++;
					}
					else if (c == 'l')
					{
						optionall = true;
						pos++;
					}
					else if (c == 'L')
					{
						optionalL = true;
						pos++;
					}
				}
			}
			/// <summary> Set the precision.</summary>
			private void  setPrecision()
			{
				int firstPos = pos;
				precisionSet = false;
				if (pos < fmt.Length && fmt[pos] == '.')
				{
					pos++;
					if ((pos < fmt.Length) && (fmt[pos] == '*'))
					{
						pos++;
						if (!setPrecisionArgPosition())
						{
							variablePrecision = true;
							precisionSet = true;
						}
						return ;
					}
					else
					{
						while (pos < fmt.Length)
						{
							char c = fmt[pos];
							if (System.Char.IsDigit(c))
								pos++;
							else
								break;
						}
						if (pos > firstPos + 1)
						{
							System.String sz = fmt.Substring(firstPos + 1, (pos) - (firstPos + 1));
							precision = System.Int32.Parse(sz);
							precisionSet = true;
						}
					}
				}
			}
			/// <summary> Set the field width.</summary>
			private void  setFieldWidth()
			{
				int firstPos = pos;
				fieldWidth = 0;
				fieldWidthSet = false;
				if ((pos < fmt.Length) && (fmt[pos] == '*'))
				{
					pos++;
					if (!setFieldWidthArgPosition())
					{
						variableFieldWidth = true;
						fieldWidthSet = true;
					}
				}
				else
				{
					while (pos < fmt.Length)
					{
						char c = fmt[pos];
						if (System.Char.IsDigit(c))
							pos++;
						else
							break;
					}
					if (firstPos < pos && firstPos < fmt.Length)
					{
						System.String sz = fmt.Substring(firstPos, (pos) - (firstPos));
						fieldWidth = System.Int32.Parse(sz);
						fieldWidthSet = true;
					}
				}
			}
			/// <summary> Store the digits <code>n</code> in %n$ forms.</summary>
			private void  setArgPosition()
			{
				int xPos;
				for (xPos = pos; xPos < fmt.Length; xPos++)
				{
					if (!System.Char.IsDigit(fmt[xPos]))
						break;
				}
				if (xPos > pos && xPos < fmt.Length)
				{
					if (fmt[xPos] == '$')
					{
						positionalSpecification = true;
						argumentPosition = System.Int32.Parse(fmt.Substring(pos, (xPos) - (pos)));
						pos = xPos + 1;
					}
				}
			}
			/// <summary> Store the digits <code>n</code> in *n$ forms.</summary>
			private bool setFieldWidthArgPosition()
			{
				bool ret = false;
				int xPos;
				for (xPos = pos; xPos < fmt.Length; xPos++)
				{
					if (!System.Char.IsDigit(fmt[xPos]))
						break;
				}
				if (xPos > pos && xPos < fmt.Length)
				{
					if (fmt[xPos] == '$')
					{
						positionalFieldWidth = true;
						argumentPositionForFieldWidth = System.Int32.Parse(fmt.Substring(pos, (xPos) - (pos)));
						pos = xPos + 1;
						ret = true;
					}
				}
				return ret;
			}
			/// <summary> Store the digits <code>n</code> in *n$ forms.</summary>
			private bool setPrecisionArgPosition()
			{
				bool ret = false;
				int xPos;
				for (xPos = pos; xPos < fmt.Length; xPos++)
				{
					if (!System.Char.IsDigit(fmt[xPos]))
						break;
				}
				if (xPos > pos && xPos < fmt.Length)
				{
					if (fmt[xPos] == '$')
					{
						positionalPrecision = true;
						argumentPositionForPrecision = System.Int32.Parse(fmt.Substring(pos, (xPos) - (pos)));
						pos = xPos + 1;
						ret = true;
					}
				}
				return ret;
			}
			/// <summary> Set flag characters, one of '-+#0 or a space.</summary>
			private void  setFlagCharacters()
			{
				/* '-+ #0 */
				thousands = false;
				leftJustify = false;
				leadingSign = false;
				leadingSpace = false;
				alternateForm = false;
				leadingZeros = false;
				for (; pos < fmt.Length; pos++)
				{
					char c = fmt[pos];
					if (c == '\'')
						thousands = true;
					else if (c == '-')
					{
						leftJustify = true;
						leadingZeros = false;
					}
					else if (c == '+')
					{
						leadingSign = true;
						leadingSpace = false;
					}
					else if (c == ' ')
					{
						if (!leadingSign)
							leadingSpace = true;
					}
					else if (c == '#')
						alternateForm = true;
					else if (c == '0')
					{
						if (!leftJustify)
							leadingZeros = true;
					}
					else
						break;
				}
			}
			/// <summary> The integer portion of the result of a decimal
			/// conversion (i, d, u, f, g, or G) will be
			/// formatted with thousands' grouping characters.
			/// For other conversions the flag is ignored.
			/// </summary>
			private bool thousands = false;
			/// <summary> The result of the conversion will be
			/// left-justified within the field.
			/// </summary>
			private bool leftJustify = false;
			/// <summary> The result of a signed conversion will always
			/// begin with a sign (+ or -).
			/// </summary>
			private bool leadingSign = false;
			/// <summary> Flag indicating that left padding with spaces is
			/// specified.
			/// </summary>
			private bool leadingSpace = false;
			/// <summary> For an o conversion, increase the precision to
			/// force the first digit of the result to be a
			/// zero.  For x (or X) conversions, a non-zero
			/// result will have 0x (or 0X) prepended to it.
			/// For e, E, f, g, or G conversions, the result
			/// will always contain a radix character, even if
			/// no digits follow the point.  For g and G
			/// conversions, trailing zeros will not be removed
			/// from the result.
			/// </summary>
			private bool alternateForm = false;
			/// <summary> Flag indicating that left padding with zeroes is
			/// specified.
			/// </summary>
			private bool leadingZeros = false;
			/// <summary> Flag indicating that the field width is *.</summary>
			private bool variableFieldWidth = false;
			/// <summary> If the converted value has fewer bytes than the
			/// field width, it will be padded with spaces or
			/// zeroes.
			/// </summary>
			private int fieldWidth = 0;
			/// <summary> Flag indicating whether or not the field width
			/// has been set.
			/// </summary>
			private bool fieldWidthSet = false;
			/// <summary> The minimum number of digits to appear for the
			/// d, i, o, u, x, or X conversions.  The number of
			/// digits to appear after the radix character for
			/// the e, E, and f conversions.  The maximum number
			/// of significant digits for the g and G 
			/// conversions.  The maximum number of bytes to be
			/// printed from a string in s and S conversions.
			/// </summary>
			private int precision = 0;
			/// <summary>Default precision. </summary>
			private const int defaultDigits = 6;
			/// <summary> Flag indicating that the precision is *.</summary>
			private bool variablePrecision = false;
			/// <summary> Flag indicating whether or not the precision has
			/// been set.
			/// </summary>
			private bool precisionSet = false;
			/*
			*/
			private bool positionalSpecification = false;
			private int argumentPosition = 0;
			private bool positionalFieldWidth = false;
			private int argumentPositionForFieldWidth = 0;
			private bool positionalPrecision = false;
			private int argumentPositionForPrecision = 0;
			/// <summary> Flag specifying that a following d, i, o, u, x,
			/// or X conversion character applies to a type
			/// short int.
			/// </summary>
			private bool optionalh = false;
			/// <summary> Flag specifying that a following d, i, o, u, x,
			/// or X conversion character applies to a type lont
			/// int argument.
			/// </summary>
			private bool optionall = false;
			/// <summary> Flag specifying that a following e, E, f, g, or
			/// G conversion character applies to a type double
			/// argument.  This is a noop in Java.
			/// </summary>
			private bool optionalL = false;
			/// <summary>Control string type. </summary>
			private char conversionCharacter = '\x0000';
			/// <summary> Position within the control string.  Used by
			/// the constructor.
			/// </summary>
			private int pos = 0;
			/// <summary>Literal or control format string. </summary>
			private System.String fmt;
		}
		/// <summary>Vector of control strings and format literals. </summary>
		private System.Collections.ArrayList vFmt = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
		/// <summary>Character position.  Used by the constructor. </summary>
		private int cPos = 0;
		/// <summary>Character position.  Used by the constructor. </summary>
		private System.Globalization.NumberFormatInfo dfs = null;
	}
}